package main

import (
	"context"
	"fmt"
	"io"
	"log"
	"net"
	"os"
	"os/signal"
	"path/filepath"
	"runtime"
	"sync"
	"sync/atomic"
	"syscall"
	"time"
)

const (
	// TCP服务器配置
	SERVER_HOST = "0.0.0.0"
	SERVER_PORT = "1883"

	// 目标服务器配置
	TARGET_HOST = "java.quanyoukeji.com"
	TARGET_PORT = "1883"

	// 是否启用消息转发
	ENABLE_FORWARD = true

	// Web管理界面端口
	WEB_PORT = 18083

	// 心跳配置
	HEARTBEAT_INTERVAL = 60 * time.Second // 心跳间隔时间
	HEARTBEAT_TIMEOUT  = 90 * time.Second // 心跳超时时间
)

// 全局变量，用于管理日志文件
var (
	globalServer   *Server
	currentLogFile *os.File
	currentLogDate string
	logFileMutex   sync.Mutex
)

// 初始化日志
func initLogger() error {
	// 创建logs目录
	if err := os.MkdirAll("logs", 0755); err != nil {
		return fmt.Errorf("创建日志目录失败: %v", err)
	}

	// 生成当前日期的日志文件名
	today := time.Now().Format("2006-01-02")
	logFileName := filepath.Join("logs", fmt.Sprintf("tcp_server_%s.log", today))

	// 打开日志文件
	logFile, err := os.OpenFile(logFileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
	if err != nil {
		return fmt.Errorf("打开日志文件失败: %v", err)
	}

	// 设置日志只输出到文件
	log.SetOutput(logFile)

	// 设置日志格式
	log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds)

	// 保存当前日志文件信息
	logFileMutex.Lock()
	currentLogFile = logFile
	currentLogDate = today
	logFileMutex.Unlock()

	// 启动日志文件检查协程
	go checkAndRotateLogFile()

	return nil
}

// 检查并轮转日志文件
func checkAndRotateLogFile() {
	ticker := time.NewTicker(1 * time.Hour) // 每小时检查一次
	defer ticker.Stop()

	for {
		select {
		case <-ticker.C:
			today := time.Now().Format("2006-01-02")

			logFileMutex.Lock()
			if currentLogDate != today {
				// 日期变化，创建新的日志文件
				newLogFileName := filepath.Join("logs", fmt.Sprintf("tcp_server_%s.log", today))
				newLogFile, err := os.OpenFile(newLogFileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
				if err != nil {
					log.Printf("创建新日志文件失败: %v", err)
					logFileMutex.Unlock()
					continue
				}

				// 关闭旧日志文件
				if currentLogFile != nil {
					currentLogFile.Close()
				}

				// 更新日志文件
				currentLogFile = newLogFile
				currentLogDate = today
				log.SetOutput(newLogFile)
				log.Printf("=== 切换到新的日志文件 ===")
			}
			logFileMutex.Unlock()
		}
	}
}

type Server struct {
	listener net.Listener
	ctx      context.Context
	cancel   context.CancelFunc
	// 当前连接数
	activeConnections int64
	// 服务器配置
	config struct {
		enableForward bool
		targetHost    string
		targetPort    string
		mu            sync.RWMutex
	}
}

type Connection struct {
	conn      net.Conn
	lastPing  time.Time
	isClosed  bool
	closeChan chan struct{}
	// 添加目标服务器连接
	targetConn net.Conn
}

func NewServer() *Server {
	ctx, cancel := context.WithCancel(context.Background())
	server := &Server{
		ctx:    ctx,
		cancel: cancel,
	}
	// 初始化配置
	server.config.enableForward = ENABLE_FORWARD
	server.config.targetHost = TARGET_HOST
	server.config.targetPort = TARGET_PORT
	return server
}

// 更新服务器配置
func (s *Server) UpdateConfig(enableForward bool, targetHost, targetPort string) {
	s.config.mu.Lock()
	defer s.config.mu.Unlock()
	s.config.enableForward = enableForward
	s.config.targetHost = targetHost
	s.config.targetPort = targetPort
}

// 获取当前配置
func (s *Server) GetConfig() (bool, string, string) {
	s.config.mu.RLock()
	defer s.config.mu.RUnlock()
	return s.config.enableForward, s.config.targetHost, s.config.targetPort
}

// 获取连接详细信息
func getConnectionInfo(conn net.Conn) string {
	tcpConn, ok := conn.(*net.TCPConn)
	if !ok {
		return conn.RemoteAddr().String()
	}
	remoteAddr := tcpConn.RemoteAddr().(*net.TCPAddr)
	return fmt.Sprintf("%s:%d", remoteAddr.IP.String(), remoteAddr.Port)
}

// 获取系统信息
func getSystemInfo() string {
	return fmt.Sprintf("系统信息 - 操作系统: %s, 架构: %s, Go版本: %s",
		runtime.GOOS, runtime.GOARCH, runtime.Version())
}

func (s *Server) Start() error {
	addr := fmt.Sprintf("%s:%s", SERVER_HOST, SERVER_PORT)
	listener, err := net.Listen("tcp", addr)
	if err != nil {
		return fmt.Errorf("无法启动服务器: %v", err)
	}
	s.listener = listener

	// 记录服务器启动信息
	log.Printf("=== 服务器启动 ===")
	log.Printf("监听地址: %s", addr)
	// log.Printf(getSystemInfo())
	log.Printf("=== 服务器启动完成 ===")

	go s.monitorStatus()
	go s.acceptConnections()
	return nil
}

func (s *Server) monitorStatus() {
	ticker := time.NewTicker(10 * time.Minute)
	defer ticker.Stop()

	for {
		select {
		case <-s.ctx.Done():
			return
		case <-ticker.C:
			active := atomic.LoadInt64(&s.activeConnections)
			log.Printf("服务器状态 - 当前连接数: %d", active)
		}
	}
}

func (s *Server) acceptConnections() {
	for {
		select {
		case <-s.ctx.Done():
			return
		default:
			conn, err := s.listener.Accept()
			if err != nil {
				log.Printf("接受连接错误: %v", err)
				continue
			}

			atomic.AddInt64(&s.activeConnections, 1)

			connection := &Connection{
				conn:      conn,
				lastPing:  time.Now(),
				closeChan: make(chan struct{}),
			}

			// 记录新连接的详细信息
			log.Printf("新连接: %s, 当前连接数: %d", getConnectionInfo(conn), atomic.LoadInt64(&s.activeConnections))

			go s.heartbeatCheck(connection)
			go s.handleConnection(connection)
		}
	}
}

func (s *Server) heartbeatCheck(conn *Connection) {
	ticker := time.NewTicker(HEARTBEAT_INTERVAL)
	defer ticker.Stop()

	for {
		select {
		case <-s.ctx.Done():
			return
		case <-conn.closeChan:
			return
		case <-ticker.C:
			if time.Since(conn.lastPing) > HEARTBEAT_TIMEOUT {
				log.Printf("连接 %s 心跳超时，关闭连接", conn.conn.RemoteAddr().String())
				conn.Close()
				return
			}
		}
	}
}

// 连接到目标服务器
func (s *Server) connectToTarget() (net.Conn, error) {
	s.config.mu.RLock()
	targetHost := s.config.targetHost
	targetPort := s.config.targetPort
	enableForward := s.config.enableForward
	s.config.mu.RUnlock()

	if !enableForward {
		return nil, fmt.Errorf("转发功能已禁用")
	}

	targetAddr := fmt.Sprintf("%s:%s", targetHost, targetPort)
	conn, err := net.Dial("tcp", targetAddr)
	if err != nil {
		return nil, fmt.Errorf("连接目标服务器失败: %v", err)
	}
	return conn, nil
}

// 将字节数组转换为十六进制字符串
func bytesToHex(data []byte) string {
	hexStr := ""
	for _, b := range data {
		hexStr += fmt.Sprintf("%02x ", b)
	}
	return hexStr
}

func (s *Server) handleConnection(conn *Connection) {
	defer func() {
		if !conn.isClosed {
			conn.Close()
		}
		atomic.AddInt64(&s.activeConnections, -1)
		log.Printf("连接关闭: %s", getConnectionInfo(conn.conn))
	}()

	var targetConn net.Conn
	var err error

	// 尝试连接到目标服务器的函数
	tryConnectTarget := func() (net.Conn, error) {
		return s.connectToTarget()
	}

	// 首次尝试连接
	s.config.mu.RLock()
	enableForward := s.config.enableForward
	s.config.mu.RUnlock()

	if enableForward {
		targetConn, err = tryConnectTarget()
		if err == nil {
			conn.targetConn = targetConn
			defer targetConn.Close()
		}
	}

	// 创建两个通道用于处理消息
	clientToTarget := make(chan []byte, 100)
	targetToClient := make(chan []byte, 100)

	// 启动客户端到目标服务器的转发协程
	go func() {
		defer close(clientToTarget)
		for {
			select {
			case <-s.ctx.Done():
				return
			case <-conn.closeChan:
				return
			case data, ok := <-clientToTarget:
				if !ok {
					return
				}
				if targetConn != nil {
					_, err := targetConn.Write(data)
					if err != nil {
						log.Printf("转发消息到目标服务器失败: %v", err)
						targetConn.Close()
						targetConn = nil
						conn.targetConn = nil
					}
				}
			}
		}
	}()

	// 启动目标服务器到客户端的转发协程
	go func() {
		defer close(targetToClient)
		buffer := make([]byte, 1024)
		for {
			select {
			case <-s.ctx.Done():
				return
			case <-conn.closeChan:
				return
			default:
				if targetConn == nil {
					time.Sleep(time.Second)
					continue
				}

				targetConn.SetReadDeadline(time.Now().Add(5 * time.Minute))
				n, err := targetConn.Read(buffer)
				if err != nil {
					if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
						continue
					}
					if err == io.EOF {
						log.Printf("目标服务器连接关闭")
						targetConn.Close()
						targetConn = nil
						conn.targetConn = nil
						continue
					}
					log.Printf("从目标服务器读取错误: %v", err)
					targetConn.Close()
					targetConn = nil
					conn.targetConn = nil
					continue
				}

				if n > 0 {
					hexMessage := bytesToHex(buffer[:n])
					log.Printf("从目标服务器收到消息: %s", hexMessage)

					// 转发到客户端
					_, err = conn.conn.Write(buffer[:n])
					if err != nil {
						log.Printf("转发消息到客户端失败: %v", err)
						return
					}
				}
			}
		}
	}()

	// 主循环：处理客户端消息
	buffer := make([]byte, 1024)
	reconnectTicker := time.NewTicker(30 * time.Second)
	defer reconnectTicker.Stop()

	for {
		select {
		case <-s.ctx.Done():
			return
		case <-conn.closeChan:
			return
		case <-reconnectTicker.C:
			// 如果启用了转发且目标连接不存在，尝试重连
			s.config.mu.RLock()
			enableForward = s.config.enableForward
			s.config.mu.RUnlock()

			if enableForward && targetConn == nil {
				newConn, err := tryConnectTarget()
				if err == nil {
					targetConn = newConn
					conn.targetConn = targetConn
					defer targetConn.Close()
				}
			}
		default:
			conn.conn.SetReadDeadline(time.Now().Add(5 * time.Minute))
			n, err := conn.conn.Read(buffer)
			if err != nil {
				if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
					log.Printf("读取超时: %s", getConnectionInfo(conn.conn))
					continue
				}
				if err == io.EOF {
					return
				}
				log.Printf("读取错误: %v", err)
				return
			}

			if n > 0 {
				conn.lastPing = time.Now()
				hexMessage := bytesToHex(buffer[:n])
				log.Printf("收到客户端消息 [%s]: %s", getConnectionInfo(conn.conn), hexMessage)

				// 如果启用了转发且目标连接不存在，尝试重连
				s.config.mu.RLock()
				enableForward = s.config.enableForward
				s.config.mu.RUnlock()

				if enableForward && targetConn == nil {
					newConn, err := tryConnectTarget()
					if err == nil {
						targetConn = newConn
						conn.targetConn = targetConn
						defer targetConn.Close()
					}
				}

				// 转发消息到目标服务器
				if enableForward && targetConn != nil {
					// 复制数据以避免并发问题
					data := make([]byte, n)
					copy(data, buffer[:n])
					select {
					case clientToTarget <- data:
					default:
						log.Printf("客户端到目标服务器的消息队列已满，丢弃消息")
					}
				}
			}
		}
	}
}

func (c *Connection) Close() {
	if !c.isClosed {
		c.isClosed = true
		if c.targetConn != nil {
			c.targetConn.Close()
		}
		c.conn.Close()
		close(c.closeChan)
	}
}

func (s *Server) Stop() {
	s.cancel()
	if s.listener != nil {
		s.listener.Close()
	}
	log.Printf("=== 服务器停止 ===")
	log.Printf("=== 服务器停止完成 ===")
}

func main() {
	// 初始化日志
	if err := initLogger(); err != nil {
		fmt.Printf("初始化日志失败: %v\n", err)
		os.Exit(1)
	}
	defer func() {
		logFileMutex.Lock()
		if currentLogFile != nil {
			currentLogFile.Close()
		}
		logFileMutex.Unlock()
	}()

	// 创建服务器实例
	globalServer = NewServer()

	// 启动Web管理服务
	startWebServer(WEB_PORT)
	log.Printf("Web管理服务已启动，访问地址: http://%s:%d", SERVER_HOST, WEB_PORT)

	// 启动服务器
	if err := globalServer.Start(); err != nil {
		log.Fatalf("服务器启动失败: %v", err)
	}

	// 等待中断信号
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
	<-sigChan

	// 优雅关闭
	globalServer.Stop()
}
